﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;

namespace WpfUIUtilities.Extensions
{
  public static class VisualTreeExtensions
  {
    /// <summary>
    /// Gets the visual ancestor.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="d"></param>
    /// <returns></returns>
    public static T GetVisualAncestor<T>(this DependencyObject d) where T : class
    {
      DependencyObject item = VisualTreeHelper.GetParent(d);

      while (item != null)
      {
        T itemAsT = item as T;
        if (itemAsT != null) return itemAsT;
        item = VisualTreeHelper.GetParent(item);
      }

      return null;
    }

    public static DependencyObject GetVisualAncestor(this DependencyObject d, Type type)
    {
      DependencyObject item = VisualTreeHelper.GetParent(d);

      while (item != null)
      {
        //if (item.GetType().IsAssignableFrom(type)) return item;
        if (item.GetType() == type) return item;
        item = VisualTreeHelper.GetParent(item);
      }

      return null;
    }

    public static T GetVisualDescendent<T>(this DependencyObject d) where T : DependencyObject
    {
      return d.GetVisualDescendents<T>().FirstOrDefault();
    }

    public static IEnumerable<T> GetVisualDescendents<T>(this DependencyObject d) where T : DependencyObject
    {
      int childCount = VisualTreeHelper.GetChildrenCount(d);

      for (int n = 0; n < childCount; n++)
      {
        DependencyObject child = VisualTreeHelper.GetChild(d, n);

        if (child is T)
        {
          yield return (T)child;
        }

        foreach (T match in GetVisualDescendents<T>(child))
        {
          yield return match;
        }
      }
    }
  }
}
